/**
 * Free software.
 */

package org.nanhill.webflow.spring;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nanhill.commons.pattern.flow.ActionContext;
import org.nanhill.commons.pattern.flow.ActionViewFlow;
import org.nanhill.commons.pattern.flow.DefaultActionContext;
import org.nanhill.commons.pattern.flow.Flow;
import org.nanhill.commons.pattern.flow.FlowFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/**
 * @author alin [xalinx at gmail dot com]
 * @date 2007-1-6
 */
public class FlowController implements Controller, InitializingBean,
		BeanFactoryAware {
	private static final Log logger = LogFactory.getLog(FlowController.class);

	/**
	 * Flow id.
	 */
	private String flowId;

	public void setFlowId(String flowId) {
		this.flowId = flowId;
	}

	private FlowFactory flowFactory;

	public void setFlowFactory(FlowFactory flowFactory) {
		this.flowFactory = flowFactory;
	}

	private BeanFactory beanFactory;

	private ActionViewFlow actionViewFlow;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	@SuppressWarnings("unchecked")
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String view = null;
		String eventId = request.getParameter("wf.event");
		ActionContext context = new DefaultActionContext(request
				.getParameterMap());
		context.setEventId(eventId);
		view = this.actionViewFlow.nextViewState(context).getView();
		return new ModelAndView(view);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		if (null == this.flowId && logger.isErrorEnabled()) {
			logger.error("flow id lost.");
		}
		if (this.flowFactory == null) {
			this.flowFactory = (FlowFactory) this.beanFactory
					.getBean("flowFactory");
		}
		if (this.flowFactory == null && logger.isErrorEnabled()) {
			logger.error("Cant't find any flow factory.");
		}
		Flow flow = this.flowFactory.getFlow(flowId);
		if (null == flow && logger.isErrorEnabled()) {
			logger.error("No such flow, flow id:" + this.flowId);
		}
		if (ActionViewFlow.class.isAssignableFrom(flow.getClass())) {
			this.actionViewFlow = (ActionViewFlow) flow;
		} else {
			if (logger.isErrorEnabled()) {
				logger
						.error("This state is not a org.nanhill.commons.pattern.flow.ActionViewState.");
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
	 */
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

}
